package com.hefan.oms.service;

import com.cat.common.entity.ResultBean;
import com.cat.common.meta.ResultCode;
import com.cat.common.meta.UserTypeEnum;
import com.cat.tiger.util.CollectionUtils;
import com.cat.tiger.util.Fraction;
import com.cat.tiger.util.GlobalConstants;
import com.cat.tiger.util.NumberUtils;
import com.google.common.collect.Maps;
import com.hefan.oms.bean.AnchorTicketMonth;
import com.hefan.oms.bean.ExchangeDetail;
import com.hefan.oms.config.OmsConfigCenter;
import com.hefan.oms.dao.AnchorTicketMonthDao;
import com.hefan.oms.dao.CurrencyExchangeDao;
import com.hefan.oms.dao.ExchangeDao;
import com.hefan.oms.itf.CurrencyExchangeService;
import com.hefan.user.bean.WebUser;
import com.hefan.user.bean.WebUserIdentity;
import com.hefan.user.itf.WebUserService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * Created by hbchen on 2016/10/10.
 */
@Component("currencyExchangeService")
public class CurrencyExchangeServiceImpl implements CurrencyExchangeService{

    @Resource
    AnchorTicketMonthDao anchorTicketMonthDao;
    @Resource
    ExchangeDao exchangeDao;
    @Resource
    CurrencyExchangeDao currencyExchangeDao;
    @Resource
    WebUserService webUserService;
    @Resource
    private OmsConfigCenter omsConfigCenter;

    @Override
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class)
    public void doMealTicketExchange(ExchangeDetail exchangeDetail) {
        AnchorTicketMonth item = new AnchorTicketMonth();
        item.setUserId(exchangeDetail.getUserId());
        item.setPayTicket((long) exchangeDetail.getHefanNum());

        SimpleDateFormat dayFormat = new SimpleDateFormat("yyyyMM");
        Calendar calendar = Calendar.getInstance();
        Integer year_months = Integer.valueOf(dayFormat.format(calendar.getTime()));

        item.setYearsMonth(year_months);

        //如果未初始化，直接初始化，如果天表已经有数据了，更新
        if (anchorTicketMonthDao.selectAnchorTicketMonthCount(item) > 0) {
            if(anchorTicketMonthDao.updateAnchorPayTicket(item)<1){
                throw new RuntimeException("更新盒饭消费记录失败");
            }
        }else {
            if(anchorTicketMonthDao.insertMealTicketUsedRecord(item)<1){
                throw new RuntimeException("新增盒饭消费记录失败");
            }
        }

        if (exchangeDao.insertExchangeDetail(exchangeDetail) < 1)
            throw new RuntimeException("新增盒饭兑换明细失败");

        if(webUserService.incrWebUserBalance(exchangeDetail.getUserId(),exchangeDetail.getFanpiaoNum())<1){
            throw new RuntimeException("新增用户饭票失败");
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class)
    public ResultBean doMealTicketExchange(ExchangeDetail exchangeDetail, WebUser webUser, WebUserIdentity webUserIdentity) {
        Integer availableTickets = exchangeDetail.getBeforeHefanNum();
        Integer hefanNum = exchangeDetail.getHefanNum();
        Integer personalIntoRatio = 0;
        Integer groupIntoRatio = 0;
        Integer platformIntoRatio = 0;
        if(UserTypeEnum.isAnchor(webUser.getUserType())) {//主播
            platformIntoRatio = webUserIdentity.getPlatformIntoRatio();
            groupIntoRatio = webUserIdentity.getGroupIntoRatio();
            personalIntoRatio = webUserIdentity.getPersonalIntoRatio();
        } else {
            Map<String,String> configMap = omsConfigCenter.getPublicConfig();
            groupIntoRatio = 0;
            if(!CollectionUtils.isEmpty(configMap) && configMap.containsKey("commUserHfToFpRatio") && configMap.containsKey("commUserHfToFpPlatformRatio")) {
                personalIntoRatio = Integer.valueOf(String.valueOf(configMap.get("commUserHfToFpRatio")));
                platformIntoRatio = Integer.valueOf(String.valueOf(configMap.get("commUserHfToFpPlatformRatio")));
            } else {
                return new ResultBean(ResultCode.UNSUCCESS.get_code(),"分成比例错误");
            }
        }
        if (availableTickets <= 0)
            return new ResultBean(ResultCode.Meal_Ticket_Not_Enough.get_code(),
                    ResultCode.Meal_Ticket_Not_Enough.getMsg());
        if (availableTickets - hefanNum <0){
            return new ResultBean(ResultCode.Meal_Ticket_Not_Enough.get_code(),
                    ResultCode.Meal_Ticket_Not_Enough.getMsg());
        }
        Map exRuleMap = currencyExchangeDao.selectByRuleType(GlobalConstants.EX_RULE_HEFAN_FANPIAO);
        if (CollectionUtils.isEmpty(exRuleMap)){
            return new ResultBean(ResultCode.UNSUCCESS.get_code(),"兑换比例错误");
        }
        Map personMap = getExchangeRuleForHeFanOrFanPiao(exRuleMap,personalIntoRatio);
        if (CollectionUtils.isEmpty(personMap) || String.valueOf(personMap.get("beExchangeRatio")).equals("0")){
            return new ResultBean(ResultCode.UNSUCCESS.get_code(),"个人兑换比例错误");
        }
        //次处是盒饭兑饭票，已知饭票数，所以要和正算反过来
        if (com.hefan.common.util.NumberUtils.divide(com.hefan.common.util.NumberUtils.multiply(exchangeDetail.getFanpiaoNum(),(Integer)personMap.get("exchangeRatio")) ,
                (Integer)personMap.get("beExchangeRatio"),0) != hefanNum)
            return new ResultBean(ResultCode.Meal_Ticket_Exchange_Rule_Is_Err.get_code(),
                    ResultCode.Meal_Ticket_Exchange_Rule_Is_Err.getMsg());
        if (groupIntoRatio>0) {
            exchangeDetail.setSuperiorHefanNum((int) com.hefan.common.util.NumberUtils.divide(com.hefan.common.util.NumberUtils.multiply(hefanNum,groupIntoRatio),100));// 经济公司／家族分成盒饭数
        }else {
            exchangeDetail.setSuperiorHefanNum(0);
        }
        // 平台分成盒饭数 = 总盒饭数 - 个人盒饭数 - 上级盒饭数
        exchangeDetail.setPlatformHefanNum(hefanNum - exchangeDetail.getSuperiorHefanNum() -(int) com.hefan.common.util.NumberUtils.divide(com.hefan.common.util.NumberUtils.multiply(hefanNum,personalIntoRatio),100,0));
        if(UserTypeEnum.isAnchor(webUser.getUserType())) {//主播
            this.doMealTicketExchange(exchangeDetail);
        } else { //普通用户
            if (exchangeDao.insertExchangeDetail(exchangeDetail) < 1)
                throw new RuntimeException("新增盒饭兑换明细失败");
            if(webUserService.incrWebUserBalanceAndHefan(exchangeDetail.getUserId(),exchangeDetail.getFanpiaoNum(),exchangeDetail.getHefanNum()*-1)<1){
                throw new RuntimeException("新增用户饭票失败");
            }
        }
        return  new ResultBean(ResultCode.SUCCESS,null);
    }


    public Map selectByRuleType(Integer exchangeRuleType) {
        Map exRuleMap =  currencyExchangeDao.selectByRuleType(exchangeRuleType);
        if (exRuleMap==null || !exRuleMap.containsKey("beExchangeRatio") || !exRuleMap.containsKey("exchangeRatio")){
            throw new RuntimeException("兑换比例查询错误");
        }
        if (Integer.valueOf(exRuleMap.get("exchangeRatio").toString()) ==0 || Integer.valueOf(exRuleMap.get("beExchangeRatio").toString()) == 0)
        {
            throw new RuntimeException("兑换比例设置错误，不可设置为0");
        }
        return exRuleMap;
    }

    /**
     * 根据兑换规则 饭票兑换盒饭
     * @param ticket
     * @param exchangeRuleType
     * @return 盒饭数
     */
    @Override
    public int exchangeFanPiao2HeFan(long ticket,Integer exchangeRuleType) {
        //饭票兑换盒饭
        Map exRuleMap = selectByRuleType(exchangeRuleType);
        double hefan = NumberUtils.divide(NumberUtils.multiply(ticket, Double.valueOf(exRuleMap.get("beExchangeRatio").toString())), Double.valueOf(exRuleMap.get("exchangeRatio").toString()));
        return Double.valueOf(hefan).intValue();
    }

    @Override
    public double exchangeFanPiao2Object(long ticket) throws Exception {
        //饭票兑换盒饭
        Map exRuleMap = selectByRuleType(GlobalConstants.EX_RULE_FANPIAO_RMB);
        double beExchangeRatio=Double.valueOf(exRuleMap.get("beExchangeRatio").toString());
        double exchangeRatio=Double.valueOf(exRuleMap.get("exchangeRatio").toString());
        return NumberUtils.divide(NumberUtils.multiply(ticket, beExchangeRatio), exchangeRatio);
    }

    private Map<String, Object> getExchangeRuleForHeFanOrFanPiao(Map exRuleMap,Integer radio){
        Map<String, Object> resultMap = Maps.newHashMap();
        Integer exchangeRatioOld =  (Integer)exRuleMap.get("exchangeRatio"); //1
        Integer beExchangeRatioOld =  (Integer)exRuleMap.get("beExchangeRatio");//10
        Fraction fraction = new Fraction(exchangeRatioOld,beExchangeRatioOld);
        Fraction fraction1 = fraction.division(radio);
        Fraction fraction2 = fraction1.division1(100);
        resultMap.put("exchangeRatio", fraction2.getNumerator());
        resultMap.put("beExchangeRatio", fraction2.getDenominator());
        return resultMap;
    }
}
